package cn.bestick.thirteenKiller.util;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;

public class MemoryImage
{
    private BufferedImage buffImg;

    public MemoryImage(int width, int height)
    {
        this.buffImg = new BufferedImage(width, height, 1);
    }

    public MemoryImage(BufferedImage buffImg)
    {
        this.buffImg = buffImg;
    }

    public MemoryImage(String fileName)
    {
        read(fileName);
    }

    public boolean read(String fileName)
    {
        try
        {
            this.buffImg = ImageIO.read(new File(fileName));
            return true;
        } catch (Exception e) {
            e.printStackTrace();
        }return false;
    }

    public void setRGB(int x, int y, int rgb)
    {
        this.buffImg.setRGB(x, y, rgb);
    }

    public int getRGB(int x, int y)
    {
        return this.buffImg.getRGB(x, y);
    }

    public int getWidth()
    {
        return this.buffImg.getWidth();
    }

    public int getHeight()
    {
        return this.buffImg.getHeight();
    }

    public boolean write(String fileName)
    {
        try
        {
            return ImageIO.write(this.buffImg,
                    fileName.substring(fileName.lastIndexOf('.') + 1),
                    new File(fileName));
        } catch (Exception e) {
            e.printStackTrace();
        }return false;
    }

    public MemoryImage copy()
    {
        return new MemoryImage(this.buffImg);
    }

    public MemoryImage copy(int x, int y, int width, int height)
    {
        MemoryImage mImg = new MemoryImage(width, height);
        for (int j = 0; j < height; j++) {
            for (int i = 0; i < width; i++) {
                mImg.setRGB(i, j, this.buffImg.getRGB(x + i, y + j));
            }
        }
        return mImg;
    }

    public boolean copy(MemoryImage dest, int dx, int dy, int sx, int sy, int width, int height)
    {
        try
        {
            for (int j = 0; j < height; j++)
                for (int i = 0; i < width; i++)
                    dest.setRGB(dx + i, dy + j, this.buffImg.getRGB(sx + i, sy + j));
        }
        catch (Exception e)
        {
            e.printStackTrace();
            return false;
        }
        return true;
    }

    public boolean copyToFile(String fileName, int x, int y, int width, int height)
    {
        MemoryImage mImg = new MemoryImage(width, height);
        try {
            for (int j = 0; j < height; j++)
                for (int i = 0; i < width; i++)
                    mImg.setRGB(i, j, this.buffImg.getRGB(x + i, y + j));
        }
        catch (Exception e)
        {
            e.printStackTrace();
            return false;
        }
        return mImg.write(fileName);
    }

    public boolean equals(MemoryImage dest)
    {
        if ((dest.getWidth() != this.buffImg.getWidth()) ||
                (dest.getHeight() != this.buffImg.getHeight())) {
            return false;
        }
        int width = dest.getWidth();
        int height = dest.getHeight();
        for (int j = 0; j < height; j++) {
            for (int i = 0; i < width; i++) {
                if (dest.getRGB(i, j) != this.buffImg.getRGB(i, j)) {
                    return false;
                }
            }
        }
        return true;
    }

    public boolean equals(MemoryImage dest, int dx, int dy, int sx, int sy, int width, int height)
    {
        try
        {
            for (int j = 0; j < height; j++) {
                for (int i = 0; i < width; i++)
                    if (dest.getRGB(i + dx, j + dy) != this.buffImg.getRGB(i + sx, j +
                            sy))
                        return false;
            }
        }
        catch (Exception e)
        {
            e.printStackTrace();
            return false;
        }
        return true;
    }

    public Point find(MemoryImage subImg)
    {
        int subWidth = subImg.getWidth();
        int subHeight = subImg.getHeight();
        int width = this.buffImg.getWidth();
        int height = this.buffImg.getHeight();
        for (int j = 0; j < height; j++) {
            for (int i = 0; i < width; i++) {
                if (equals(subImg, 0, 0, i, j, subWidth, subHeight)) {
                    return new Point(i, j);
                }
            }
        }
        return null;
    }

    public BufferedImage getBufferedImage()
    {
        return this.buffImg;
    }
}